package com.wei.czz.framework.admin.manager;

import com.wei.czz.common.enums.CommonEnum;
import com.wei.czz.common.enums.ResultEnum;
import com.wei.czz.common.exception.CzzException;
import com.wei.czz.common.po.UserPo;
import com.wei.czz.common.utils.SecurityUtils;
import com.wei.czz.framework.admin.entity.UserRoleEntity;
import com.wei.czz.framework.admin.service.UserRoleService;
import com.wei.czz.framework.common.service.TransactionService;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 *
 * @author wyw
 * date: 2024-06-15 14:01:05
 * className: UserRoleManager
 * version: 1.0
 * description:
 */
@Component
@AllArgsConstructor
public class UserRoleManager {

    private static final Logger log = LoggerFactory.getLogger(UserRoleManager.class);

    private final UserRoleService userRoleService;

    private final TransactionService transactionService;

    public void saveUserRole(Long userId, List<Long> roleIdList, Integer relationMode) {
        // 获取操作用户
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        Integer deleteStatus = null;
        if (roleIdList.isEmpty()) {
            deleteStatus = CommonEnum.ZERO.getValue();
        }

        /*
            获取用户关联角色
         */
        List<UserRoleEntity> userRoleList = userRoleService.findList(userId, null, deleteStatus);

        List<UserRoleEntity> haveDeleteList = new ArrayList<>();
        Map<Long, UserRoleEntity> userRoleMap = new HashMap<>();
        for (UserRoleEntity roleMenu : userRoleList) {
            if (CommonEnum.ONE.getValue().equals(roleMenu.getDeleteStatus())) {
                haveDeleteList.add(roleMenu);
                continue;
            }
            userRoleMap.put(roleMenu.getRoleId(), roleMenu);
        }
        Iterator<UserRoleEntity> userRoleIterator = haveDeleteList.iterator();

        List<UserRoleEntity> saveList = new ArrayList<>();
        List<UserRoleEntity> updateList = new ArrayList<>();

        if (roleIdList.isEmpty()) {
            // 用户新关联角色为空，用户已关联角色不为空
            for (UserRoleEntity userRole : userRoleMap.values()) {
                UserRoleEntity updateUserRole = new UserRoleEntity();
                updateUserRole.setId(userRole.getId())
                        .setDeleteStatus(CommonEnum.ONE.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateUserRole);
            }
        } else if (userRoleMap.isEmpty()) {
            // 用户新关联角色不为空，用户已关联角色为空

            for (Long roleId : roleIdList) {
                // 用户新关联角色
                if (userRoleIterator.hasNext()) {
                    // 利用已删除的数据
                    UserRoleEntity updateUserRole = userRoleIterator.next();
                    updateUserRole.setUserId(userId)
                            .setRoleId(roleId)
                            .setRelationMode(relationMode)
                            .setDeleteStatus(CommonEnum.ZERO.getValue())
                            .setUpdateTime(date)
                            .setUpdateUser(userPo.getUsername())
                            .setUpdateUserId(userPo.getUserId());
                    updateList.add(updateUserRole);
                } else {
                    // 新增数据
                    UserRoleEntity saveUserRole = this.getUserRole(userId, roleId, relationMode, userPo, date);
                    saveList.add(saveUserRole);
                }
            }

        } else {
            // 用户新关联角色不为空，用户已关联角色不为空

            for (Long roleId : roleIdList) {
                UserRoleEntity userRole = userRoleMap.remove(roleId);
                if (Objects.nonNull(userRole)) {
                    log.debug("用户已关联该角色。roleId={} menuId={}", userId, roleId);
                    continue;
                }
                // 用户新关联角色
                if (userRoleIterator.hasNext()) {
                    // 利用已删除的数据
                    UserRoleEntity updateUserRole = userRoleIterator.next();
                    updateUserRole.setUserId(userId)
                            .setRoleId(roleId)
                            .setRelationMode(relationMode)
                            .setDeleteStatus(CommonEnum.ZERO.getValue())
                            .setUpdateTime(date)
                            .setUpdateUser(userPo.getUsername())
                            .setUpdateUserId(userPo.getUserId());
                    updateList.add(updateUserRole);
                } else {
                    // 新增数据
                    UserRoleEntity saveUserRole = this.getUserRole(userId, roleId, relationMode, userPo, date);
                    saveList.add(saveUserRole);
                }
            }
            // 遍历用户与角色映射，剩余数据全部删除
            for (UserRoleEntity userRole : userRoleMap.values()) {
                UserRoleEntity updateUserRole = new UserRoleEntity();
                updateUserRole.setId(userRole.getId())
                        .setDeleteStatus(CommonEnum.ONE.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateUserRole);
            }
        }

        transactionService.execute(() -> {
            if (!saveList.isEmpty()) {
                userRoleService.batchSave(saveList);
            }
            if (!updateList.isEmpty()) {
                userRoleService.batchUpdate(updateList);
            }
        });
    }

    public void saveRoleUser(Long roleId, List<Long> userIdList, Integer relationMode) {
        // 获取操作用户
        UserPo userPo = SecurityUtils.getUser();
        Date date = new Date();

        Integer deleteStatus = null;
        if (userIdList.isEmpty()) {
            deleteStatus = CommonEnum.ZERO.getValue();
        }

        /*
            获取角色关联用户
         */
        List<UserRoleEntity> userRoleList = userRoleService.findList(null, roleId, deleteStatus);

        List<UserRoleEntity> haveDeleteList = new ArrayList<>();
        Map<Long, UserRoleEntity> userRoleMap = new HashMap<>();
        for (UserRoleEntity roleMenu : userRoleList) {
            if (CommonEnum.ONE.getValue().equals(roleMenu.getDeleteStatus())) {
                haveDeleteList.add(roleMenu);
                continue;
            }
            userRoleMap.put(roleMenu.getUserId(), roleMenu);
        }
        Iterator<UserRoleEntity> userRoleIterator = haveDeleteList.iterator();

        List<UserRoleEntity> saveList = new ArrayList<>();
        List<UserRoleEntity> updateList = new ArrayList<>();

        if (userIdList.isEmpty()) {
            // 用户新关联角色为空，用户已关联角色不为空
            for (UserRoleEntity userRole : userRoleMap.values()) {
                UserRoleEntity updateUserRole = new UserRoleEntity();
                updateUserRole.setId(userRole.getId())
                        .setDeleteStatus(CommonEnum.ONE.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateUserRole);
            }
        } else if (userRoleMap.isEmpty()) {
            // 用户新关联角色不为空，用户已关联角色为空

            for (Long userId : userIdList) {
                // 角色新关联用户
                if (userRoleIterator.hasNext()) {
                    // 利用已删除的数据
                    UserRoleEntity updateUserRole = userRoleIterator.next();
                    updateUserRole.setUserId(userId)
                            .setRoleId(roleId)
                            .setRelationMode(relationMode)
                            .setDeleteStatus(CommonEnum.ZERO.getValue())
                            .setUpdateTime(date)
                            .setUpdateUser(userPo.getUsername())
                            .setUpdateUserId(userPo.getUserId());
                    updateList.add(updateUserRole);
                } else {
                    // 新增数据
                    UserRoleEntity saveUserRole = this.getUserRole(userId, roleId, relationMode, userPo, date);
                    saveList.add(saveUserRole);
                }
            }

        } else {
            // 用户新关联角色不为空，用户已关联角色不为空

            for (Long userId : userIdList) {
                UserRoleEntity userRole = userRoleMap.remove(roleId);
                if (Objects.nonNull(userRole)) {
                    log.debug("角色已关联该用户。roleId={} userId={}", roleId, userId);
                    continue;
                }
                // 角色新关联用户
                if (userRoleIterator.hasNext()) {
                    // 利用已删除的数据
                    UserRoleEntity updateUserRole = userRoleIterator.next();
                    updateUserRole.setUserId(userId)
                            .setRoleId(roleId)
                            .setRelationMode(relationMode)
                            .setDeleteStatus(CommonEnum.ZERO.getValue())
                            .setUpdateTime(date)
                            .setUpdateUser(userPo.getUsername())
                            .setUpdateUserId(userPo.getUserId());
                    updateList.add(updateUserRole);
                } else {
                    // 新增数据
                    UserRoleEntity saveUserRole = this.getUserRole(userId, roleId, relationMode, userPo, date);
                    saveList.add(saveUserRole);
                }
            }
            // 遍历用户与角色映射，剩余数据全部删除
            for (UserRoleEntity userRole : userRoleMap.values()) {
                UserRoleEntity updateUserRole = new UserRoleEntity();
                updateUserRole.setId(userRole.getId())
                        .setDeleteStatus(CommonEnum.ONE.getValue())
                        .setUpdateTime(date)
                        .setUpdateUser(userPo.getUsername())
                        .setUpdateUserId(userPo.getUserId());
                updateList.add(updateUserRole);
            }
        }

        transactionService.execute(() -> {
            if (!saveList.isEmpty()) {
                userRoleService.batchSave(saveList);
            }
            if (!updateList.isEmpty()) {
                userRoleService.batchUpdate(updateList);
            }
        });

    }

    public void unassociatedUserRole(List<Long> relationIdList) {

        /*
            获取用户关联角色
         */
        List<UserRoleEntity> userRoleList = userRoleService.getList(relationIdList);
        if (userRoleList.isEmpty()) {
            throw new CzzException(ResultEnum.NOT_FOUND);
        }

        /*
            解除用户关联角色
         */
        userRoleService.unassociatedUserRole(relationIdList);
    }


    /**
     * 获取用户与角色实体对象
     * @return 用户与角色实体对象
     */
    private UserRoleEntity getUserRole(Long userId, Long roleId, Integer relationMode, UserPo userPo, Date date) {
        UserRoleEntity userRole = new UserRoleEntity();
        userRole.setUserId(userId)
                .setRoleId(roleId)
                .setRelationMode(relationMode)
                .setDeleteStatus(CommonEnum.ZERO.getValue())
                .setUpdateTime(date)
                .setUpdateUser(StringUtils.EMPTY)
                .setUpdateUserId(CommonEnum.ZERO.getLongValue())
                .setCreateTime(date)
                .setCreateUser(userPo.getUsername())
                .setCreateUserId(userPo.getUserId());
        return userRole;
    }

}
